/*
    $Header: /Windows/Shell/ShellExt.root/ShellExt/src/CCmdStub.h 1     08-01-05 0:08 Ken $
    $Log: /Windows/Shell/ShellExt.root/ShellExt/src/CCmdStub.h $
 * 
 * 1     08-01-05 0:08 Ken

*/

#pragma once
#include <list>
//#include <atlbase.h>
//#include <atlcom.h>
//#include <ExDisp.h>
//#include <ExDispid.h>
#include <commctrl.h>
#include "atlstr.h"

using namespace std;
using namespace ATL;

class CCmdStub;
class CCmdStubWnd;


//
// echo: the first line after idle is the echo string!
// idle: after the cmd prompt "X:xxx\xx>", the cmd is in Idle
//
class CCmdStub
{
public:
    CCmdStub();
    ~CCmdStub();
public:
    BOOL Init(CCmdStubWnd* pCmdWrapWnd, IWebBrowser2* pIWebBrowser);

public:
    BOOL Send2Cmd(const BYTE* pInput, DWORD dwSize);
    void SetCurPath(TCHAR* pszPath);
    BOOL SetPathAutoSync(BOOL bSyncOn);
    const TCHAR* GetCurDir(){return m_szCurPath;};

private:
static DWORD WINAPI RcvFromCmdProc(LPVOID pThis);
    void RcvFromCmd();

//
// help functions
private:
    void ChgCmdDir(TCHAR* pDir);

private:
    CCmdStubWnd* m_pCmdWrapWnd;
    IWebBrowser2* m_pIWebBrowser;

private:
    BOOL m_bIdl;
    BOOL m_bPathSync;
    BOOL m_bChgPathPend;
    TCHAR m_szCurPath[MAX_PATH];

    HANDLE m_hpipeRd;
    HANDLE m_hpipeWt;
    HANDLE m_hShlPipeIn;
    HANDLE m_hShlPipeOut;

    HANDLE m_hRcvThread;

    HANDLE m_hCmdProc;

private:
    TCHAR m_szFilterStr[MAX_PATH];

};

//
// caret associated key deal!
// copy/past/cut deal!
//
class CCmdStubWnd
{
public:
    CCmdStubWnd();
    ~CCmdStubWnd();

public:
    void Init(CCmdStub* pcCmd){m_pcCmd=pcCmd;};
    HWND GetWnd(){return m_hWnd;};

public:
    // need deal the special input chars, like;"backspace"
    void AppendOutString(TCHAR* pszOut);
    BOOL SetInputTypeChar(BOOL bTypeChar);

public:
    HWND CreateCmdStubWnd(HWND hwndParent);
protected:
static    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
    LRESULT (CALLBACK *m_pfnDefEditProc)(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
//    void OnSize(HWND hWnd);
    virtual LRESULT VOnKeyDown(HWND hWnd,  WPARAM wParam, LPARAM lParam);
    virtual LRESULT VOnChar(HWND hWnd,  WPARAM wParam, LPARAM lParam);
    virtual LRESULT VOnSysChar(HWND hWnd,  WPARAM wParam, LPARAM lParam);
    virtual LRESULT VOnClearCutPast(HWND hWnd, UINT uMessage);
    virtual LRESULT VOnFocusChange(BOOL fFocus);

private:
    TCHAR* AppendOutBuf(TCHAR* pOut, DWORD dwLen);
    BOOL GetUseInput(TCHAR* pszInput, DWORD* pdwLen);
    void RemoveUserInput();
    void RePlaceUserInput(TCHAR* pszBuf);
enum enHistory{HISTORY_PREV, HISTORY_NEXT, HISTORY_TOP, HISTORY_BOTTOM};
    void ShowHistory(enum enHistory enHis);
    void ResetHistoryPointer(){m_itHis=m_lstszHistory.begin();};
    BOOL RunAs(TCHAR* pCmd);

private:
    BOOL m_bInuptTypeChar;
    DWORD m_dwInputStart;
    CCmdStub* m_pcCmd;

private:
    HWND m_hWnd;

    list<CString> m_lstszHistory;
    list<CString>::iterator m_itHis;

private:
    DWORD m_dwBSNum;    // tmp var
};
